package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.dto.ResponseCode;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.request.SwitchCabinetCreateReqDTO;
import com.huaxin.device.dto.request.SwitchCabinetPageListReqDTO;
import com.huaxin.device.dto.request.SwitchCabinetUpdateReqDTO;
import com.huaxin.device.mapper.ElectricalEquipmentMapper;
import com.huaxin.device.mapper.SwitchCabinetMapper;
import com.huaxin.device.mapping.SwitchCabinetMapping;
import com.huaxin.device.models.SwitchCabinet;
import com.huaxin.device.service.SwitchCabinetService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.webjars.NotFoundException;

import java.util.List;

import static org.springframework.util.StringUtils.hasText;

@Service
@RequiredArgsConstructor
public class SwitchCabinetServiceImpl extends ServiceImpl<SwitchCabinetMapper, SwitchCabinet> implements SwitchCabinetService {

    private final ApplicationContext applicationContext;
    private final SwitchCabinetMapping mapping;
    private final SwitchCabinetMapper mapper;
    private final ElectricalEquipmentMapper electricalEquipmentMapper;

    @Override
    public ResponseResult<SwitchCabinet> create(SwitchCabinetCreateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        // 检查 cabinetCode + roomId + familyId + orgId 是否已存在
        if (existsByFields(SwitchCabinet::getCabinetCode, in.getCabinetCode(), in.getRoomId(), in.getFamilyId(), in.getOrgId(), null)) {
            return ResponseResult.failure(ResponseCode.BAD_REQUEST, "编号已存在", null);
        }
        // 检查 cabinetName + roomId + familyId + orgId 是否已存在
        if (existsByFields(SwitchCabinet::getCabinetName, in.getCabinetName(), in.getRoomId(), in.getFamilyId(), in.getOrgId(), null)) {
            return ResponseResult.failure(ResponseCode.BAD_REQUEST, "变电箱名称已存在", null);
        }

        SwitchCabinet entity = mapping.toEntity(in);
        if (!save(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "添加失败，请稍后再试！", null);
        }
        SwitchCabinet created = getById(entity.getId());
        return ResponseResult.ok(created);
    }

    @Override
    public SwitchCabinet getByCabinetId(String id) {
        if (id == null || id.trim().isEmpty()) {
            throw new IllegalArgumentException("ID不能为空");
        }
        SwitchCabinet entity = getById(id);
        if (entity == null) {
            throw new NotFoundException("变电箱不存在");
        }
        return entity;
    }

    @Override
    public ResponseResult<String> update(SwitchCabinetUpdateReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        SwitchCabinet entity = getByCabinetId(in.getId());

        // 检查 cabinetCode + roomId + familyId + orgId 是否已存在
        if (existsByFields(SwitchCabinet::getCabinetCode, in.getCabinetCode(), in.getRoomId(), in.getFamilyId(), in.getOrgId(), entity.getId())) {
            return ResponseResult.failure(ResponseCode.BAD_REQUEST, "编号已存在", null);
        }
        // 检查 cabinetName + roomId + familyId + orgId 是否已存在
        if (existsByFields(SwitchCabinet::getCabinetName, in.getCabinetName(), in.getRoomId(), in.getFamilyId(), in.getOrgId(), entity.getId())) {
            return ResponseResult.failure(ResponseCode.BAD_REQUEST, "变电箱名称已存在", null);
        }

        mapping.updateEntity(in, entity);
        if (!updateById(entity)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "更新失败，请稍后再试！", null);
        }
        return ResponseResult.ok("更新成功");
    }

    @Override
    public ResponseResult<String> delete(String id) {
        SwitchCabinet entity = getByCabinetId(id);

        // 检查该变电箱下是否有设备
        if (electricalEquipmentMapper.existsBySwitchCabinetId(entity.getId())) {
            return ResponseResult.failure(ResponseCode.BAD_REQUEST, "该变电箱下有设备，请先删除设备", null);
        }

        boolean removed = this.applicationContext.getBean(SwitchCabinetService.class).removeById(id);
        if (!removed) {
            return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
        }
        return ResponseResult.ok("删除成功！");
    }

    @Override
    public ResponseResult<IPage<SwitchCabinet>> pageQuery(SwitchCabinetPageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }

        IPage<SwitchCabinet> page = new Page<>(in.getPageNum(), in.getPageSize());
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();

        // 关键字搜索：名称、编号、位置
        if (hasText(in.getKeyword())) {
            wrapper.and(w -> w.like(SwitchCabinet::getCabinetName, in.getKeyword())
                    .or().like(SwitchCabinet::getCabinetCode, in.getKeyword())
                    .or().like(SwitchCabinet::getLocation, in.getKeyword()));
        }

        // 类型过滤
        if (hasText(in.getType())) {
            wrapper.eq(SwitchCabinet::getType, in.getType());
        }

        // 所属配电房
        if (hasText(in.getRoomId())) {
            wrapper.eq(SwitchCabinet::getRoomId, in.getRoomId());
        }

        // 所属组织
        if (hasText(in.getOrgId())) {
            wrapper.eq(SwitchCabinet::getOrgId, in.getOrgId());
        }

        // 家庭ID过滤
        if (hasText(in.getFamilyId())) {
            wrapper.eq(SwitchCabinet::getFamilyId, in.getFamilyId());
        }

        // 按创建时间倒序
        wrapper.orderByDesc(SwitchCabinet::getCreatedAt);

        IPage<SwitchCabinet> resultPage = page(page, wrapper);
        return ResponseResult.ok(resultPage);
    }

    @Override
    public List<SwitchCabinet> getByRoomId(String roomId) {
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SwitchCabinet::getRoomId, roomId);
        return list(wrapper);
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByIds(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SwitchCabinet::getId, ids);
        return ResponseResult.ok(list(wrapper));
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByOrgId(String orgId) {
        if (orgId == null) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SwitchCabinet::getOrgId, orgId);
        return ResponseResult.ok(list(wrapper));
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByOrgIds(List<String> orgIds) {
        if (orgIds == null || orgIds.isEmpty()) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SwitchCabinet::getOrgId, orgIds);
        return ResponseResult.ok(list(wrapper));
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByFamilyId(String familyId) {
        if (familyId == null) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SwitchCabinet::getFamilyId, familyId);
        return ResponseResult.ok(list(wrapper));
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByFamilyIds(List<String> familyIds) {
        if (familyIds == null || familyIds.isEmpty()) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SwitchCabinet::getFamilyId, familyIds);
        return ResponseResult.ok(list(wrapper));
    }

    @Override
    public ResponseResult<List<SwitchCabinet>> listByType(String type) {
        if (type == null) {
            return ResponseResult.ok(List.of());
        }
        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SwitchCabinet::getType, type);
        return ResponseResult.ok(list(wrapper));
    }

    /**
     * 检查多个字段值组合是否已存在（排除当前ID）
     *
     * @param fieldGetter 字段Getter
     * @param fieldValue  字段值
     * @param roomId      配电房ID
     * @param familyId    家庭ID
     * @param orgId       组织ID
     * @param excludeId   要排除的ID（可为null）
     * @return 是否存在匹配记录
     */
    private boolean existsByFields(
            SFunction<SwitchCabinet, ?> fieldGetter,
            Object fieldValue,
            String roomId,
            String familyId,
            String orgId,
            String excludeId) {

        if (fieldGetter == null) return false;

        LambdaQueryWrapper<SwitchCabinet> wrapper = new LambdaQueryWrapper<>();

        if (fieldValue == null ||
                (fieldValue instanceof CharSequence cs && cs.toString().trim().isEmpty())) {
            wrapper.and(wrapper1 -> wrapper1
                    .isNull(fieldGetter)
                    .or().eq(fieldGetter, "")
            );
        } else {
            wrapper.eq(fieldGetter, fieldValue.toString().trim());
        }

        if (roomId == null || roomId.trim().isEmpty()) {
            wrapper.and(wrapper1 -> wrapper1
                    .isNull(SwitchCabinet::getRoomId)
                    .or().eq(SwitchCabinet::getRoomId, "")
            );
        } else {
            wrapper.eq(SwitchCabinet::getRoomId, roomId.trim());
        }

        if (familyId == null || familyId.trim().isEmpty()) {
            wrapper.and(wrapper1 -> wrapper1
                    .isNull(SwitchCabinet::getFamilyId)
                    .or().eq(SwitchCabinet::getFamilyId, "")
            );
        } else {
            wrapper.eq(SwitchCabinet::getFamilyId, familyId.trim());
        }

        if (orgId == null || orgId.trim().isEmpty()) {
            wrapper.and(wrapper1 -> wrapper1
                    .isNull(SwitchCabinet::getOrgId)
                    .or().eq(SwitchCabinet::getOrgId, "")
            );
        } else {
            wrapper.eq(SwitchCabinet::getOrgId, orgId.trim());
        }

        if (excludeId != null && !excludeId.trim().isEmpty()) {
            wrapper.ne(SwitchCabinet::getId, excludeId.trim());
        }

        return this.count(wrapper) > 0;
    }
}